#include <stdio.h>

void f(int a)
{
	switch(a) {
		case 1:
		case 2:
		case 7:
		case 10:
			printf("1, 2, 7, 10\n");
			break;
		case 3:
		case 4:
		case 5:
		case 6:
			printf("3, 4, 5, 6\n");
			break;
		case 8:
		case 9:
		case 20:
		case 21:
			printf("8, 9, 20, 21\n");
			break;
		case 22:
			printf("22\n");
			break;
		default:
			printf("default.\n");
			break;
	}
}

int main()
{
	f(4);
}

#if 0

编译器会通过某种派发机制来降低代码的冗余度。

/*
 * gcc
 */
	在编译这种多对一的swith语句时，GCC会生成统一的转移表。

/*
 * ARM64
 */
	因为输入值为零的情况没有对应的处理方法，所以GCC会从输入值为1的特例开始枚举各个分支，以便把转移表压缩得尽可能小。

	能把所有的偏移量信息编码为8位字节型数据，封装在单条指令的opcode里。

	arm64程序的每条指令都对应着4个字节的opcode。

	本例这种类型的小型代码中，各分支偏移量的具体数值不会很大。GCC能够充分利用这一现象，构造出单字节指针组成的转移表。

#endif

#if 0
/*
 * intel
 */
0000000000001149 <f>:
    1149:	f3 0f 1e fa          	endbr64 
    114d:	55                   	push   %rbp
    114e:	48 89 e5             	mov    %rsp,%rbp
    1151:	48 83 ec 10          	sub    $0x10,%rsp
    1155:	89 7d fc             	mov    %edi,-0x4(%rbp)
    1158:	83 7d fc 16          	cmpl   $0x16,-0x4(%rbp)
    115c:	77 5c                	ja     11ba <f+0x71>
    115e:	8b 45 fc             	mov    -0x4(%rbp),%eax
    1161:	48 8d 14 85 00 00 00 	lea    0x0(,%rax,4),%rdx
    1168:	00 
    1169:	48 8d 05 c4 0e 00 00 	lea    0xec4(%rip),%rax        # 2034 <_IO_stdin_used+0x34>
    1170:	8b 04 02             	mov    (%rdx,%rax,1),%eax
    1173:	48 98                	cltq   
    1175:	48 8d 15 b8 0e 00 00 	lea    0xeb8(%rip),%rdx        # 2034 <_IO_stdin_used+0x34>
    117c:	48 01 d0             	add    %rdx,%rax
    117f:	3e ff e0             	notrack jmpq *%rax
    1182:	48 8d 3d 7b 0e 00 00 	lea    0xe7b(%rip),%rdi        # 2004 <_IO_stdin_used+0x4>
    1189:	e8 c2 fe ff ff       	callq  1050 <puts@plt>
    118e:	eb 37                	jmp    11c7 <f+0x7e>
    1190:	48 8d 3d 79 0e 00 00 	lea    0xe79(%rip),%rdi        # 2010 <_IO_stdin_used+0x10>
    1197:	e8 b4 fe ff ff       	callq  1050 <puts@plt>
    119c:	eb 29                	jmp    11c7 <f+0x7e>
    119e:	48 8d 3d 76 0e 00 00 	lea    0xe76(%rip),%rdi        # 201b <_IO_stdin_used+0x1b>
    11a5:	e8 a6 fe ff ff       	callq  1050 <puts@plt>
    11aa:	eb 1b                	jmp    11c7 <f+0x7e>
    11ac:	48 8d 3d 75 0e 00 00 	lea    0xe75(%rip),%rdi        # 2028 <_IO_stdin_used+0x28>
    11b3:	e8 98 fe ff ff       	callq  1050 <puts@plt>
    11b8:	eb 0d                	jmp    11c7 <f+0x7e>
    11ba:	48 8d 3d 6a 0e 00 00 	lea    0xe6a(%rip),%rdi        # 202b <_IO_stdin_used+0x2b>
    11c1:	e8 8a fe ff ff       	callq  1050 <puts@plt>
    11c6:	90                   	nop
    11c7:	90                   	nop
    11c8:	c9                   	leaveq 
    11c9:	c3                   	retq   

00000000000011ca <main>:
    11ca:	f3 0f 1e fa          	endbr64 
    11ce:	55                   	push   %rbp
    11cf:	48 89 e5             	mov    %rsp,%rbp
    11d2:	bf 04 00 00 00       	mov    $0x4,%edi
    11d7:	e8 6d ff ff ff       	callq  1149 <f>
    11dc:	b8 00 00 00 00       	mov    $0x0,%eax
    11e1:	5d                   	pop    %rbp
    11e2:	c3                   	retq   
    11e3:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
    11ea:	00 00 00 
    11ed:	0f 1f 00             	nopl   (%rax)

/*
 * arm
 */
000000000040055c <f>:
  40055c:	a9be7bfd 	stp	x29, x30, [sp, #-32]!
  400560:	910003fd 	mov	x29, sp
  400564:	b9001fa0 	str	w0, [x29, #28]
  400568:	b9401fa0 	ldr	w0, [x29, #28]
  40056c:	7100241f 	cmp	w0, #0x9
  400570:	5400014c 	b.gt	400598 <f+0x3c>
  400574:	7100201f 	cmp	w0, #0x8
  400578:	5400034a 	b.ge	4005e0 <f+0x84>  // b.tcont
  40057c:	7100181f 	cmp	w0, #0x6
  400580:	5400020c 	b.gt	4005c0 <f+0x64>
  400584:	71000c1f 	cmp	w0, #0x3
  400588:	5400024a 	b.ge	4005d0 <f+0x74>  // b.tcont
  40058c:	7100041f 	cmp	w0, #0x1
  400590:	5400038b 	b.lt	400600 <f+0xa4>  // b.tstop
  400594:	1400000b 	b	4005c0 <f+0x64>
  400598:	7100541f 	cmp	w0, #0x15
  40059c:	540000cc 	b.gt	4005b4 <f+0x58>
  4005a0:	7100501f 	cmp	w0, #0x14
  4005a4:	540001ea 	b.ge	4005e0 <f+0x84>  // b.tcont
  4005a8:	7100281f 	cmp	w0, #0xa
  4005ac:	540000a0 	b.eq	4005c0 <f+0x64>  // b.none
  4005b0:	14000014 	b	400600 <f+0xa4>
  4005b4:	7100581f 	cmp	w0, #0x16
  4005b8:	540001c0 	b.eq	4005f0 <f+0x94>  // b.none
  4005bc:	14000011 	b	400600 <f+0xa4>
  4005c0:	90000000 	adrp	x0, 400000 <_init-0x3e8>
  4005c4:	911ba000 	add	x0, x0, #0x6e8
  4005c8:	97ffffa2 	bl	400450 <puts@plt>
  4005cc:	14000011 	b	400610 <f+0xb4>
  4005d0:	90000000 	adrp	x0, 400000 <_init-0x3e8>
  4005d4:	911be000 	add	x0, x0, #0x6f8
  4005d8:	97ffff9e 	bl	400450 <puts@plt>
  4005dc:	1400000d 	b	400610 <f+0xb4>
  4005e0:	90000000 	adrp	x0, 400000 <_init-0x3e8>
  4005e4:	911c2000 	add	x0, x0, #0x708
  4005e8:	97ffff9a 	bl	400450 <puts@plt>
  4005ec:	14000009 	b	400610 <f+0xb4>
  4005f0:	90000000 	adrp	x0, 400000 <_init-0x3e8>
  4005f4:	911c6000 	add	x0, x0, #0x718
  4005f8:	97ffff96 	bl	400450 <puts@plt>
  4005fc:	14000005 	b	400610 <f+0xb4>
  400600:	90000000 	adrp	x0, 400000 <_init-0x3e8>
  400604:	911c8000 	add	x0, x0, #0x720
  400608:	97ffff92 	bl	400450 <puts@plt>
  40060c:	d503201f 	nop
  400610:	d503201f 	nop
  400614:	a8c27bfd 	ldp	x29, x30, [sp], #32
  400618:	d65f03c0 	ret

000000000040061c <main>:
  40061c:	a9bf7bfd 	stp	x29, x30, [sp, #-16]!
  400620:	910003fd 	mov	x29, sp
  400624:	52800080 	mov	w0, #0x4                   	// #4
  400628:	97ffffcd 	bl	40055c <f>
  40062c:	52800000 	mov	w0, #0x0                   	// #0
  400630:	a8c17bfd 	ldp	x29, x30, [sp], #16
  400634:	d65f03c0 	ret


#endif

